package xyz.thoughtset.viewer.common.crud.api.controller;


import org.springframework.context.ApplicationEventPublisher;
import xyz.thoughtset.viewer.common.api.controller.BaseController;
import xyz.thoughtset.viewer.common.core.factory.AnnMgtFactory;
import xyz.thoughtset.viewer.common.crud.api.factory.CrudApiPowerMgtFactory;
import xyz.thoughtset.viewer.common.crud.core.service.BaseService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import xyz.thoughtset.viewer.common.annotation.log.DataOptLog;
import xyz.thoughtset.viewer.common.log.entity.event.LogMsgEvent;

import javax.naming.NoPermissionException;
import java.util.Objects;

@Slf4j
public abstract class CrudController extends BaseController {
	@Autowired
	private CrudApiPowerMgtFactory crudApiPowerMgtFactory;

	@Autowired
	protected AnnMgtFactory annMgtFactory;
	@Autowired
	protected ApplicationEventPublisher eventPublisher;

	protected BaseService findQueryService(String objType, String method){
		return findAndCheckCService(objType, method, false);
	}
	@SneakyThrows
	protected BaseService findCommandService(String objType, String method){
		return findAndCheckCService(objType, method, true);
	}

	@SneakyThrows
	private BaseService findAndCheckCService(String objType, String method,boolean wasCmdApi){
		BaseService server = findService(objType,wasCmdApi);
		boolean f = crudApiPowerMgtFactory.checkPower(objType, method, wasCmdApi);
		if (!f) throw new NoPermissionException("API check failed");
		return server;
	}

	@SneakyThrows
	private BaseService findService(String objType, boolean wasCmdApi){
		BaseService server = crudApiPowerMgtFactory.targetService(objType,wasCmdApi);
		if (Objects.isNull(server)) throw new NoSuchFieldException("No such service");
		return server;
	}

	protected Object saveOptLog(String subject, String active, Object data) {
		return saveOptLog(subject, active, data,null);
	}
	protected Object saveOptLog(String subject, String active, Object data,String pk) {
		boolean f = annMgtFactory.hasObjExist(subject, DataOptLog.class);
		if (f){
			LogMsgEvent logMsgEvent = new LogMsgEvent(this, data, active, subject,pk);
			eventPublisher.publishEvent(logMsgEvent);
		}
		return data;
	}


}
